/*
 ============================================================================
 Name       : Log.cpp
 Author   : 
 Version     : 1.0
 Copyright   : 
 Description : CLog implementation
 ============================================================================
 */

#include "Log.h"

#include <f32file.h>
#include <utf.h>

static CLog* sInstance = NULL;

CLog::CLog( RFs& aFs, const TDesC& aFileName )
    : iFs( aFs )
    {
    iLogFileName.Copy( aFileName );
    }

CLog::~CLog()
    {
    iBuffer.Close();
    iBuffer16.Close();
    sInstance = NULL;
    }

CLog* CLog::NewLC( RFs& aFs, const TDesC& aFileName )
    {
    CLog* self = new (ELeave) CLog( aFs, aFileName );
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }

CLog* CLog::NewL( RFs& aFs, const TDesC& aFileName )
    {
    CLog* self = CLog::NewLC( aFs, aFileName );
    CleanupStack::Pop(self);
    return self;
    }

void CLog::ConstructL()
    {
    if ( sInstance )
        {
        User::Leave( KErrAlreadyExists );
        }
    sInstance = this;
    iBuffer.CreateL( 16 * 1024 );
    iBuffer16.CreateL( 16 * 1024 );
#ifdef LOGGING
    RFile log;
    log.Replace( iFs, iLogFileName, EFileWrite );
    log.Close();
#endif
    }

void CLog::Delete()
    {
    delete sInstance;
    sInstance = NULL;
    }

void CLog::Log( TRefByValue< const TDesC8 > aFormat, ... )
    {
    VA_LIST va;
    VA_START( va, aFormat );
    TRAP_IGNORE( sInstance->DoLogL( aFormat, va ) );
    VA_END( va );
    }

void CLog::Log( TRefByValue< const TDesC > aFormat, ... )
    {
    VA_LIST va;
    VA_START( va, aFormat );
    TRAP_IGNORE( sInstance->DoLogL( aFormat, va ) );
    VA_END( va );
    }

_LIT8( KNewLine, "\r\n" );

void CLog::DoLogL( TRefByValue< const TDesC > aFormat, VA_LIST aVarArgList )
    {
    RFile log;
    User::LeaveIfError( log.Open( iFs, iLogFileName, EFileWrite ) );
    TInt pos = 0;
    log.Seek( ESeekEnd, pos );
    iBuffer16.FormatList( aFormat, aVarArgList );
    iBuffer.Zero();
    CnvUtfConverter::ConvertFromUnicodeToUtf8( iBuffer, iBuffer16 );
    
    // Add timestamp
    TTime time;
    time.HomeTime();
    TBuf<255> timeBuff;
    _LIT(KTimeFormat, "%:0%H%:1%T%:2%S.%*C3%:3");
    time.FormatL(timeBuff, KTimeFormat);
    TBuf8<255> buf8;
    buf8.Copy(timeBuff);
    buf8.Append(_L8(" "));
    iBuffer.Insert(0, buf8);
    
    log.Write( iBuffer );
    log.Write( KNewLine() );
    log.Close();
    }

void CLog::DoLogL( TRefByValue< const TDesC8 > aFormat, VA_LIST aVarArgList )
    {
    RFile log;
    User::LeaveIfError( log.Open( iFs, iLogFileName, EFileWrite ) );
    TInt pos = 0;
    log.Seek( ESeekEnd, pos );
    iBuffer.FormatList( aFormat, aVarArgList );
    
    // Add timestamp
    TTime time;
    time.HomeTime();
    TBuf<255> timeBuff;
    _LIT(KTimeFormat, "%:0%H%:1%T%:2%S.%*C3%:3");
    time.FormatL(timeBuff, KTimeFormat);
    TBuf8<255> buf8;
    buf8.Copy(timeBuff);
    buf8.Append(_L8(" "));
    iBuffer.Insert(0, buf8);
    
    log.Write( iBuffer );
    log.Write( KNewLine() );
    log.Close();
    }

